#include "Communications_Handler.h"

uint8 u8IIC_TxBuffer [IIC_TX_BUFFER_SIZE] = { "ABCDEFGHIJ" };       //BORRAR CONTENIDO

#pragma DATA_SEG MY_ZEROPAGE

uint8 u8VSCI_TxBuffer [VSCI_TX_BUFFER_SIZE];
uint8 u8IIC_TxCount;

uint8 u8VSCI_RxBuffer = 0;

uint8 u8VSCI_TxState = VSCI_TX_IDLE;

volatile uint8 u8IIC_Temp;

extern uint16 u16GPS_distance;
extern uint16 u16GPS_Altitude;
extern uint16 u16Course;
extern uint8 u8Ctrl2planeAngle;
extern uint8 u8Speedkm;
extern uint8 u8PositionFix;
extern uint8 u8Satellites;
extern uint16 u16GPS_RelativeAltitude;

void vfnComm_BuildIICPacket (void)
{
    uint8 u8counter;     
    
    u8IIC_TxBuffer[0] = u16GPS_distance >> 8;
    u8IIC_TxBuffer[1] = (uint8)u16GPS_distance; 
    u8IIC_TxBuffer[2] = u16GPS_Altitude >> 8;
    u8IIC_TxBuffer[3] = (uint8)u16GPS_RelativeAltitude; //plane altitude respect to controller (*10). Zero if negative
    u8IIC_TxBuffer[4] = (uint8)u16Course >> 2;  //from 0 to 180
    u8IIC_TxBuffer[5] = u8Ctrl2planeAngle;
    u8IIC_TxBuffer[6] = u8Speedkm;
    u8IIC_TxBuffer[7] = u8PositionFix;
    u8IIC_TxBuffer[8] = u8Satellites;
    u8IIC_TxBuffer[9] = 0;    //ultrasound_altitude
    u8IIC_TxBuffer[10] = 0; // checksum
    
    for (u8counter = 0; u8counter < IIC_TX_BUFFER_SIZE - 1; u8counter++)
    {
        u8IIC_TxBuffer[10] ^= u8IIC_TxBuffer[u8counter];        
    }
       
}

void vfnIIC_Init (void)
{
    vfnIIC_SetAddress (0xCC);
    vfnIIC_BaudRate (IIC_BAUDRATE_100KBPS);
    vfnIIC_ModuleStatus (IIC_MODULE_ENABLED);
    vfnIIC_InterruptStatus (IIC_INTERRUPTS_ENABLED);
}

void vfnIIC_SlaveReadWrite (void) 
{
    if (u8IIC_SlaveStatus())   // Check for Slave Receive or transmit
    {     
        vfnIIC_DataDirection (IIC_TRANSMIT);// Set Tx bit to begin a Transmit
        vfnIIC_SendData (u8IIC_TxBuffer[u8IIC_TxCount]);
        u8IIC_TxCount++;
    } 
    else 
    {
        vfnIIC_DataDirection (IIC_RECEIVE); // Switch to RX mode
        (void)u8IIC_ReadData();            // Dummy read from Data Register    
    }
}


void vfnIIC_SlaveReadStore (void) 
{
    u8IIC_Temp = u8IIC_ReadData(); 
    
    if (u8IIC_Temp == 0x50)
    {
        //prueba = 0x23;
    }
    else 
    {
    }
}


interrupt 17 void IIC_ISR (void)   // IIC interrupt vector number = 17 (S08) 
{                                                                             
    vfnIIC_ClearInterruptFlag();   // Clear Interrupt Flag
    
    if (!u8IIC_MasterMode())       // Slave?  nomas pa chekar... no vaya a ser
    { 

        if (u8IIC_CheckIfAdressed()) 
        {                
            u8IIC_TxCount = 0;
            vfnIIC_SlaveReadWrite();
        }
        else 
        {
            if (u8IIC_TransmitMode())  // Check for ACK received
            {                
                if (!u8IIC_AckReceived())    // ACK Recieved
                {             
                    vfnIIC_SendData (u8IIC_TxBuffer[u8IIC_TxCount]);
                    u8IIC_TxCount++;
           
                }
                else 
                {
                    vfnIIC_DataDirection (IIC_RECEIVE); // Switch to RX mode
                    (void)u8IIC_ReadData ();            // Dummy read from Data Register
                    //u8IIC_RequestCounter++;
                }
            } 
            else 
            {
                vfnIIC_SlaveReadStore();
            }
        }
    }
}

/* For speed purposes, this functions bypass the layered architecture*/
#pragma INLINE
void vfnVSCI_SendByte (uint8 u8byte)
{
	uint8 u8counter;

	// Clear timer flag just in case
	(void)TPMC1SC_CH1F;
	TPMC1SC_CH1F = 0;
		
	// Start bit	
	VSCI_TX_PIN = 0;
	TPMC1V = TPMCNT + VSCI_TIMER_DELAY_START_BIT;
	
	while(!TPMC1SC_CH1F);
	TPMC1SC_CH1F = 0;	// CLEAR FLAG
	
	u8counter = 8;
	
	while(u8counter)
	{
		if (u8byte & 0x01)
		{
			VSCI_TX_PIN = 1;
		}
		else
		{
			VSCI_TX_PIN = 0;
		}
		
		TPMC1V += VSCI_TIMER_DELAY_VALUE;
		u8byte >>= 1;
		u8counter--;
		
		while(!TPMC1SC_CH1F);
		TPMC1SC_CH1F = 0;	// CLEAR FLAG
	}
	
	VSCI_TX_PIN = 1;	  // stop bit
	TPMC1V += VSCI_TIMER_DELAY_VALUE;
	
	while(!TPMC1SC_CH1F); 
	TPMC1SC_CH1F = 0;	// CLEAR FLAG

}

#pragma INLINE
uint8 u8VSCI_ReadByte (void)
{
	uint8 u8temp_buffer;
	uint8 u8counter;
	
	// Clear flag just in case
	(void)TPMC1SC_CH1F;
	TPMC1SC_CH1F = 0;
	
	TPMC1V = TPMCNT + VSCI_TIMER_HALF_DELAY;
	
	while(!TPMC1SC_CH1F);
	TPMC1SC_CH1F = 0;	// CLEAR FLAG
	
	if(VSCI_RX_PIN != 0)
	{
		return 0;
	}
	u8counter = 8;
	
	while(u8counter)
	{
		TPMC1V += VSCI_TIMER_DELAY_VALUE;
		
		while(!TPMC1SC_CH1F);
		TPMC1SC_CH1F = 0;	// CLEAR FLAG
		
		u8temp_buffer >>= 1;
		if(VSCI_RX_PIN)
		{
			u8temp_buffer |= 0x80;
		}
		u8counter--;	
	}
	
	TPMC1V += VSCI_TIMER_DELAY_VALUE;
	
	while(!TPMC1SC_CH1F);
	TPMC1SC_CH1F = 0;	// CLEAR FLAG
	
	if (VSCI_RX_PIN != 1)
	{
		return 0;
	}

	return u8temp_buffer;
}

void vfnVSCI_Configure (void)
{
	VSCI_TX_PIN = 1;
	
	VSCI_TX_PIN_DD = GPIO_OUTPUT;
	VSCI_RX_PIN_DD = GPIO_INPUT;

	vfnTPM_SetModulo (0x0000);
	
	vfnTPM_SetPrescalerDivider (TPM_PRESCALER_1);
	
	vfnTPM_Channel1OutputCompare ();
	
	vfnTPM_SelectClock (TPM_CLK_BUS);
			
}

void vfnComm_BuildVSCIPacket (void)
{
    uint8 u8counter;
    
    u8VSCI_TxBuffer[0] = u16GPS_distance >> 8;
    //u8VSCI_TxBuffer[0] = 0x01;
    u8VSCI_TxBuffer[1] = (uint8)u16GPS_distance; 
    //u8VSCI_TxBuffer[1] = 0x23;
    u8VSCI_TxBuffer[2] = (uint8)(u16GPS_RelativeAltitude >> 8);
	//u8VSCI_TxBuffer[2] = 2;    
    u8VSCI_TxBuffer[3] = (uint8)u16GPS_RelativeAltitude; //plane altitude respect to controller (*10). Zero if negative
    //u8VSCI_TxBuffer[3] = 128;
    u8VSCI_TxBuffer[4] = (uint8)(u16Course >> 1);  //from 0 to 180
    //u8VSCI_TxBuffer[4] = 121;
    u8VSCI_TxBuffer[5] = u8Ctrl2planeAngle;
    //u8VSCI_TxBuffer[5] = 60;
    u8VSCI_TxBuffer[6] = u8Speedkm;
    //u8VSCI_TxBuffer[6] = 32;
    //u8VSCI_TxBuffer[7] = 5;
    u8VSCI_TxBuffer[7] = u8PositionFix;
    u8VSCI_TxBuffer[8] = u8Satellites;
    u8VSCI_TxBuffer[9] = 0;    //ultrasound_altitude
    u8VSCI_TxBuffer[10] = 0; // checksum
        
    for (u8counter = 0; u8counter < VSCI_TX_BUFFER_SIZE - 1; u8counter++)
    {
        u8VSCI_TxBuffer[10] ^= u8VSCI_TxBuffer[u8counter];        
    }
       
}

